{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "from manim import *\n",
    "config.media_width = \"100%\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "class CodeVideo(Scene):\n",
    "    def problem_desc(self):\n",
    "        '''\n",
    "        问题介绍\n",
    "        全体自然数的平方的倒数和等于多少？这是著名的巴塞尔问题。\n",
    "        现有的对这个问题的解答方法有很多，\n",
    "        但在当时这个问题刚刚被提出的时候却难倒了一众数学家。\n",
    "        直到 [欧拉] 的出现才第一次解决了这个问题，\n",
    "        所以这个问题就以 [公式] 的故乡—瑞士的巴塞尔进行命名了。\n",
    "        下面，我们首先来看看欧拉是如何解决这个问题的。\n",
    "        '''\n",
    "        # Markup 是一种标记语言\n",
    "        # 参考 https://chenliangjing.me/2019/10/11/Playground-Markup-%E8%AF%AD%E6%B3%95/\n",
    "        text1 = MarkupText(\"<big>问题介绍</big>\")\n",
    "        text3 = MarkupText(\"<small>全体自然数的平方的倒数和等于多少</small>\")\n",
    "        \n",
    "        # 前面添加 r 是为了不要 里面的内容 转义\n",
    "        f_a = ['1','2','3','4',r'\\dots','n']\n",
    "        f = []\n",
    "        for x in f_a:\n",
    "            if x == r'\\dots':\n",
    "                f.append(x)\n",
    "            else:\n",
    "                f.append(r'\\frac{1}{%s^{2} } ' %(x))\n",
    "            f.append(\"+\")\n",
    "        f = f[0:-1]\n",
    "        f.append('=?')\n",
    "        \n",
    "        text2 = MathTex(*f)\n",
    "        text2_anm = []\n",
    "        for x in text2:\n",
    "            x.set_color(random_color())\n",
    "            text2_anm.append(Write(x))\n",
    "          \n",
    "        g = VGroup(text1, text2,text3).arrange(DOWN,buff=1)\n",
    "        # self.add(g)\n",
    "        self.play(*[Write(text1)])\n",
    "        self.wait()\n",
    "        for x in text2_anm:\n",
    "            self.play(x,run_time=0.3)\n",
    "        self.play(Write(text3),run_time=1)\n",
    "        self.wait(3)\n",
    "        self.play(FadeOut(g),run_time=1)\n",
    "        \n",
    "    def construct(self):\n",
    "        self.problem_desc()\n",
    "        self.setp_1()\n",
    "        self.setp_2()\n",
    "        \n",
    "    def gen_x3(self):\n",
    "        '''\n",
    "        画出 x^2+3x+2 的图像\n",
    "        '''\n",
    "        \n",
    "        axes = Axes(\n",
    "            x_range=[-5, 5, 1],\n",
    "            y_range=[-10, 10, 1],\n",
    "            x_length=config.frame_width/2,\n",
    "            axis_config={\"color\": GREEN},\n",
    "            # x_axis_config={\n",
    "            #     \"numbers_to_include\": np.arange(-10, 10.01, 2),\n",
    "            #     \"numbers_with_elongated_ticks\": np.arange(-10, 10.01, 2),\n",
    "            # },\n",
    "            tips=False,\n",
    "            color = GRAY_E,\n",
    "            fill_opacity=1\n",
    "        )\n",
    "        axes_labels = axes.get_axis_labels()\n",
    "        \n",
    "        # 函数表达式\n",
    "        x3_graph = axes.plot(lambda x: np.power(x,2)+3*x+2)\n",
    "    \n",
    "\n",
    "        x3_graph_lab = axes.get_graph_label(\n",
    "            x3_graph, \"x^2+3x+2\", x_val=1\n",
    "        )\n",
    "        \n",
    "        plot = VGroup(axes, axes_labels,x3_graph_lab)\n",
    "        # 围绕一个 长方形 在函数图像上面\n",
    "        sur = SurroundingRectangle(plot,color=GRAY_E,fill_opacity=1,buff=0.1,)\n",
    "        \n",
    "        # 定义一个 变化函数 当函数图像变化时 跟随变化\n",
    "        def sur_upt(o):\n",
    "            o.become(SurroundingRectangle(plot,color=GRAY_E,fill_opacity=1,buff=0.1,))\n",
    "        sur.add_updater(sur_upt)\n",
    "        \n",
    "        self.add(sur,plot)\n",
    "        # plot.add(sur)\n",
    "        self.play(Create(x3_graph))\n",
    "        plot.add(x3_graph)\n",
    "        \n",
    "        for x in range(-2,0,1):\n",
    "            # 输入 x的值 得到 函数上的点的坐标\n",
    "            d = Dot(axes.i2gp(x, x3_graph))\n",
    "            t = Tex('$%d$' %(x))\n",
    "            t.next_to(d,DOWN)\n",
    "            l = Line(d.get_center(),t.get_center())\n",
    "            ann = [Create(d),Create(t),Create(l)]\n",
    "            self.play(*ann)\n",
    "            plot.add(d,t,l)\n",
    "        self.wait()\n",
    "        self.play(plot.animate.scale(0.5))\n",
    "        self.wait()\n",
    "        # self.play(plot.animate.to_edge(UR))\n",
    "        \n",
    " \n",
    "        \n",
    "    def setp_1(self):\n",
    "        '''\n",
    "        第一步\n",
    "        首先，让我们来思考一个问题，如何将函数  写成一个无穷乘积的形式？\n",
    "        '''\n",
    "        text1 = Text('首先，让我们来思考一个问题?').scale(0.8)\n",
    "        text2 = Text('如何将下面的公式，写成一个无穷乘积的形式').scale(0.8)\n",
    "        text3 = Tex(\"$f(x)=sin(x)$\").scale(2).set_color(YELLOW)\n",
    "        g = Group(text1,text2,text3).arrange(DOWN,buff=0.5)\n",
    "        self.play(GrowFromCenter(g))\n",
    "        self.wait(4)\n",
    "        self.play(g.animate.shift(UP*config.frame_height))\n",
    "        self.wait()\n",
    "        \n",
    "        \n",
    "        # 所谓因式分解就是将一个多项式写为多个因式乘积的形式，比如\n",
    "        text1 = Text('所谓无穷乘积就是因式分解').scale(0.8)\n",
    "        text2 = Text('就是将一个多项式写为多个因式乘积的形式，比如').scale(0.8)\n",
    "        text3 = Tex('$x^2+3x+2=$','$(x+1)(x+2)$',color=RED).scale(2)\n",
    "        g2 = Group(text1,text2,text3).arrange(DOWN,buff=0.5)\n",
    "        self.play(*[Write(text1),Write(text2)])\n",
    "        self.wait()\n",
    "        self.play(Write(text3[0]))\n",
    "        self.wait()\n",
    "        text3[1].set_color(YELLOW)\n",
    "        \n",
    "        \n",
    "        self.gen_x3()\n",
    "        \n",
    "        self.play(Write(text3[1]))\n",
    "        \n",
    "        text4 = Text('对于一个多项式来讲，它如果可以被分解为').scale(0.8)\n",
    "        g2.add(text4)\n",
    "        g2.arrange(DOWN,buff=0.5)\n",
    "        self.play(Write(text4))\n",
    "        text5 = Tex('$P(x)=x^n+a_1\\cdot x^{n-1}+\\dots+a_n=(x-x_1)\\cdot(x-x_2)\\cdots (x-x_n)$').scale(1).set_color(YELLOW)\n",
    "        g2.add(text5)\n",
    "        text3.scale(0.5)\n",
    "        g2.arrange(DOWN,buff=0.5)\n",
    "        self.play(Write(text5))\n",
    "        self.wait()\n",
    "        # self.play(g2.animate.shift(UP*config.frame_height/2))\n",
    "        \n",
    "        text6 = Tex('$x_1 x_2 \\cdots x_n$')\n",
    "        g2.add(text6)\n",
    "        g2.arrange(DOWN,buff=0.5)\n",
    "        self.play(Write(text6))\n",
    "        \n",
    "        text7 = Text('上面的x值就是在 P(x)=0 时的全体解')\n",
    "        \n",
    "        g2.add(text7)\n",
    "        g2.arrange(DOWN,buff=0.5)\n",
    "        self.play(Write(text7))\n",
    "        self.wait(3)\n",
    "        self.clear()\n",
    "        \n",
    "        # self.play(FadeOut(g2))\n",
    "        \n",
    "    def setp_2(self):\n",
    "        '''\n",
    "        现在我们回过头来看函数 ，这不是一个多项式，\n",
    "        但我们仍可以将其写为无穷个多项式乘积的形式。\n",
    "        首先，我们需要明确 [公式] 的零点都在哪里：\n",
    "        '''\n",
    "        text1= Text('现在问题变为')\n",
    "        text2= Tex('$f(x)=sin(x)$',color=YELLOW).scale(2)\n",
    "        text3= Text('零点在哪里？')\n",
    "        g = Group(text1,text2,text3).arrange(DOWN,buff=0.5)\n",
    "        self.play(GrowFromCenter(g))\n",
    "        self.wait(3)\n",
    "        self.play(FadeOut(g))\n",
    "        \n",
    "        \n",
    "        axes = Axes(\n",
    "            x_range=[-10, 10.3, 1],\n",
    "            y_range=[-1.5, 1.5, 1],\n",
    "            x_length=10,\n",
    "            axis_config={\"color\": GREEN},\n",
    "            # x_axis_config={\n",
    "            #     \"numbers_to_include\": np.arange(-10, 10.01, 2),\n",
    "            #     \"numbers_with_elongated_ticks\": np.arange(-10, 10.01, 2),\n",
    "            # },\n",
    "            tips=False,\n",
    "        )\n",
    "        axes_labels = axes.get_axis_labels()\n",
    "        sin_graph = axes.plot(lambda x: np.sin(x), color=BLUE)\n",
    "    \n",
    "\n",
    "        sin_label = axes.get_graph_label(\n",
    "            sin_graph, \"\\\\sin(x)\", x_val=-10, direction=UP / 2\n",
    "        )\n",
    "        print(axes.i2gp(PI/2, sin_graph))\n",
    "     \n",
    "        # vert_line = axes.get_vertical_line(\n",
    "        #     axes.i2gp(PI/2, sin_graph), color=YELLOW, line_func=Line\n",
    "        # )\n",
    "        \n",
    "      \n",
    "        plot = VGroup(axes,axes_labels,sin_label)\n",
    "        labels = VGroup(axes_labels, sin_label)\n",
    "        self.add(plot)\n",
    "        self.play(Create(sin_graph))\n",
    "        plot.add(sin_graph)\n",
    "        self.wait()\n",
    "\n",
    "        for x in range(-3,4,1):\n",
    "            d = Dot(axes.i2gp(PI*x, sin_graph))\n",
    "            if x == 0 :\n",
    "                t = Tex('$0$')\n",
    "            else:\n",
    "                t = Tex('$%d\\pi$' %(x)) \n",
    "            t.next_to(d,DOWN*5)\n",
    "            l = DashedLine(d.get_center(),t.get_center())\n",
    "            self.add(d,t,l)\n",
    "            plot.add(d,t,l)\n",
    "        self.wait(2)\n",
    "        \n",
    "        # 从这里往下就是公式变换了\n",
    "        text_1 = Tex(\n",
    "            \"$sin(x)$\",\n",
    "            \"$=$\",\n",
    "            \"$(x-0)$\",\n",
    "            r\"$(1-\\frac{x}{\\pi })$\",\n",
    "            r\"$(1+\\frac{x}{\\pi })$\",\n",
    "            r\"$(1-\\frac{x}{2\\pi })$\",\n",
    "            r\"$(1+\\frac{x}{2\\pi })$\",\n",
    "            r\"$\\dots$\"\n",
    "            )\n",
    "        \n",
    "        g3 = Group(plot,text_1).arrange(DOWN)\n",
    "        for i,x in enumerate( text_1 ):\n",
    "            self.play(Create(x),run_time=0.5)\n",
    "        self.wait(2)\n",
    "        \n",
    "        text_2 = Tex(\n",
    "            \"$sin(x)$\",\n",
    "            \"$=$\",\n",
    "            \"$x$\",\n",
    "            r\"$(1-\\frac{x^2}{\\pi^2 })$\",\n",
    "            r\"$(1-\\frac{x^2}{(2\\pi)^2 })$\",\n",
    "            r\"$\\dots$\",\n",
    "            r\"$(1-\\frac{x^2}{(n\\pi)^2 })$\",\n",
    "            )\n",
    "        g3.add(text_2)\n",
    "        g3.arrange(DOWN,buff=0.1)\n",
    "        \n",
    "        for i,x in enumerate( text_2[:2] ):\n",
    "            self.play(Create(x))\n",
    "        self.play(TransformFromCopy(text_1[2],text_2[2]))\n",
    "        self.wait()\n",
    "        self.play(TransformFromCopy(text_1[3:5],text_2[3]))\n",
    "        self.wait()\n",
    "        self.play(TransformFromCopy(text_1[5:7],text_2[4]))\n",
    "        self.wait()\n",
    "        for i,x in enumerate( text_2[-2:] ):\n",
    "            self.play(Create(x))\n",
    "        self.wait(6)\n",
    "        #  移除 函数图像\n",
    "        self.play(plot.animate.shift(LEFT*15))\n",
    "        g3.remove(plot)\n",
    "       \n",
    "        text_5 = MathTex(r'sin(x)=x\\cdot \\prod_{ k=1}^{+\\infty} (1-\\frac{x^2}{k^2x^2} )')\n",
    "        g3.add(text_5)\n",
    "        g3.arrange(DOWN,buff=0.5,aligned_edge=LEFT)\n",
    "      \n",
    "        self.play(Create(text_5))\n",
    "        self.wait()\n",
    "        text_6 = Text('取出连乘号里最前面的3项并记做')\n",
    "        text_7 = Tex(\n",
    "            \"$sin_3(x)$\",\n",
    "            \"$=$\",\n",
    "            \"$x$\",\n",
    "            r\"$(1-\\frac{x^2}{\\pi^2 })$\",\n",
    "            r\"$(1-\\frac{x^2}{(2\\pi)^2 })$\",\n",
    "             r\"$(1-\\frac{x^2}{(3\\pi)^2 })$\",\n",
    "           \n",
    "            )\n",
    "        g3.add(text_6,text_7)\n",
    "        g3.arrange(DOWN,buff=0.5,aligned_edge=LEFT)\n",
    "        self.play(Create(text_6))\n",
    "        self.wait()\n",
    "        self.play(Create(text_7))\n",
    "        self.wait(6)\n",
    "        \n",
    "        for x in g3:\n",
    "            if x != text_7:\n",
    "                self.play(FadeOut(x),run_time=0.2)\n",
    "                g3.remove(x)\n",
    "        g3.arrange(DOWN,buff=0.5,aligned_edge=LEFT)\n",
    "        self.wait()\n",
    "        \n",
    "        text_8 = MathTex(r'sin_3(x)=T_3(x)-\\frac{x^3}{\\pi ^2} -\\frac{x^3}{2^2\\pi ^2} -\\frac{x^3}{3^2\\pi ^2} ')\n",
    "        g3.add(text_8)\n",
    "        g3.arrange(DOWN,buff=0.5,aligned_edge=LEFT)\n",
    "        self.play(Create(text_8))\n",
    "        self.wait()\n",
    "        \n",
    "        text_9 = MathTex(r'sin_n(x)=T_n(x)-x^3\\sum_{k=1}^{n}  \\frac{1}{k^2\\pi ^2} ')\n",
    "        g3.add(text_9)\n",
    "        g3.arrange(DOWN,buff=0.5,aligned_edge=LEFT)\n",
    "        self.play(Create(text_9))\n",
    "        self.wait()\n",
    "        \n",
    "        text_10 = MathTex(\n",
    "            r'sin_n(x)\\to sin(x)=T(x)-',\n",
    "        r'x^3\\sum_{k=1}^{n}  \\frac{1}{k^2\\pi ^2} ',\n",
    "        r'(n\\to \\infty )'\n",
    "        )\n",
    "        g3.add(text_10)\n",
    "        g3.arrange(DOWN,buff=0.5,aligned_edge=LEFT)\n",
    "        self.play(Create(text_10))\n",
    "        self.wait()\n",
    "        \n",
    "        text_11 = Text('又知道sin(x)幂级数展开式:').scale(0.5)\n",
    "        text_12 = MathTex(r'sin(x) = T(x)- ',r'\\frac{x^3}{3!}')\n",
    "        \n",
    "        g3.add(text_11,text_12)\n",
    "        g3.arrange(DOWN,buff=0.2,aligned_edge=LEFT)\n",
    "        self.play(Create(text_11))\n",
    "        self.play(Create(text_12))\n",
    "        self.wait(5)\n",
    "        \n",
    "    \n",
    "        \n",
    "        for x in g3:\n",
    "            if x not in [text_10,text_12]:\n",
    "                self.play(FadeOut(x),run_time=0.2)\n",
    "                g3.remove(x)\n",
    "        g3.arrange(DOWN,buff=0.2,aligned_edge=LEFT)\n",
    "        self.wait()\n",
    "        \n",
    "        text_13 = MathTex(\n",
    "            r'\\frac{x^3}{3!}',\n",
    "            '=',\n",
    "            r'x^3\\sum_{k=1}^{n}  \\frac{1}{k^2\\pi ^2} '\n",
    "            )\n",
    "        g3.add(text_13)\n",
    "        g3.arrange(DOWN,buff=0.2,aligned_edge=LEFT)\n",
    "        self.play(TransformFromCopy(text_12[1],text_13[0]))\n",
    "        self.play(TransformFromCopy(text_10[1],text_13[2]))\n",
    "        self.play(Create(text_13[1]))\n",
    "        self.wait(3)\n",
    "        \n",
    "        for x in g3:\n",
    "            if x not in [text_13]:\n",
    "                self.play(FadeOut(x),run_time=0.2)\n",
    "                g3.remove(x)\n",
    "        g3.arrange(DOWN,buff=0.2,aligned_edge=LEFT)\n",
    "        \n",
    "        text_14 = MathTex(r'\\Longrightarrow \\frac{1}{6}=\\frac{1}{\\pi^2} \\sum_{k=1}^{n}  \\frac{1}{k^2} ')\n",
    "        g3.add(text_14)\n",
    "       \n",
    "\n",
    "        text_15 = MathTex(r'\\Longrightarrow \\frac{\\pi^2}{6}= \\sum_{k=1}^{n}  \\frac{1}{k^2} = 1+\\frac{1}{2^2} +\\frac{1}{3^2} +\\dots +\\frac{1}{n^2} ')\n",
    "        g3.add(text_15)\n",
    "        g3.arrange(DOWN,buff=0.2,aligned_edge=LEFT)\n",
    "        \n",
    "        self.play(Create(text_14))\n",
    "        self.wait()\n",
    "        self.play(Create(text_15))\n",
    "        self.wait(5)\n",
    "        self.clear()\n",
    "        \n",
    "        \n",
    "    def oula(self):\n",
    "        \n",
    "        oula = ImageMobject('assets/images.jpg')\n",
    "        oula.width = config.frame_width/2.5\n",
    "        t = Text('欧拉 Leonhard Paul Euler').scale(0.5)\n",
    "        t2 = Text('1707年4月15日－1783年9月18日').scale(0.5)\n",
    "        t1 = Text('此问题由他证明').scale(0.5)\n",
    "        g = Group(oula,t,t2,t1).arrange(DOWN,buff=0.5)\n",
    "        self.play(FadeIn(oula))\n",
    "        self.wait(6)\n",
    "        self.play(Write(t))\n",
    "        self.play(Write(t2))\n",
    "        self.play(Write(t1))\n",
    "        self.wait(6)\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "                                                                                                                 \r"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0.69989967 2.         0.        ]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "                                                                                                                                                                                                                 \r"
     ]
    },
    {
     "data": {
      "text/html": [
       "<video src=\"media\\jupyter\\CodeVideo@2022-04-10@21-32-33.mp4\" controls autoplay loop style=\"max-width: 100%;\"  >\n",
       "      Your browser does not support the <code>video</code> element.\n",
       "    </video>"
      ],
      "text/plain": [
       "<IPython.core.display.Video object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%manim -v WARNING -qh CodeVideo"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Gitee不支持2M以上的视频，请前往[知乎-巴塞尔问题](https://zhuanlan.zhihu.com/p/496230168)查看\n",
    "\n",
    "另外第二题的答案为：\n",
    "$$\n",
    "\\lim_{n \\to \\infty}\n",
    "  \\sqrt{1 + 2 \\sqrt{1 + 3 \\sqrt{1 + \\cdots \\sqrt{1 + (n - 1) \\sqrt{1 + n}}}}}\n",
    "= 3.\n",
    "$$"
   ]
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "2c0948b606a87f16a1329dbdb4c9bf2c1b73f2116240f6b736465dcfd150b23b"
  },
  "kernelspec": {
   "display_name": "Python 3.8.12 ('manim')",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.12"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
